import pprint

from bson import ObjectId

from config import col_activity, col_register, col_institution, col_alumni, col_institution_top11, col_okr, col_top11e, \
    col_activity_institution, col_institution_top11e
from datetime import datetime, timedelta


def inst_query(inst_id):
    inst_id = ObjectId(inst_id)

    return {"$or": [{"institution_id": inst_id},
                    {"co_inst_ids": inst_id}]}


def month_range(year, month=1):
    s_m = month
    e_m = month + 1
    s_y = year
    e_y = year
    # next year
    if e_m > 12:
        e_y = e_y + 1
        e_m = e_m % 12

    from_date = datetime(s_y, s_m, 1)  # 默认当前年份的第一天的时刻 epoch_year
    to_date = datetime(e_y, e_m, 1)

    return {"$gte": from_date,
            "$lt": to_date}


def institution_task_top_by_month(inst_id: str, year, month=0):
    """
    详细榜单
    """
    year = year if year else datetime.utcnow().year
    month = month if month else datetime.utcnow().month
    query = inst_query(inst_id)
    query["is_deleted"] = {"$ne": True}

    query['end_time'] = month_range(year, month)

    act_docs = col_activity.find(query).distinct("_id")
    total_activities = len(act_docs)

    pipeline = [
        {"$match": {"is_attended": True, "activity_id": {"$in": list(act_docs)}}},
        {"$lookup": {
            "from": "institution",
            "let": {"institution_ref_id": "$institution_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$institution_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"ocode": 1, "_id": 0}}
            ],
            "as": 'institution'
        }},
        # 过滤无效的引用
        {"$match": {"institution.0": {"$exists": True}}},
        {"$project": { "institution_id": 1, "activity_id": 1}},
    ]

    reg_docs = col_activity_institution.aggregate(pipeline)

    reg_docs = list(reg_docs) if reg_docs else []

    total_participants = len(reg_docs)

    # 激活指标
    activate_indicators_count = 0
    # 数量指标
    quantity_indicators_count = 0

    indicators = set()

    for doc in reg_docs:
        if doc.get("institution_id") not in indicators:
            quantity_indicators_count += 1
            indicators.add(doc.get("institution_id"))

    okr = col_okr.find_one({"year": year, "dept_id": inst_id})
    if okr:
        ration = round(quantity_indicators_count / okr.get("okr", 0.000001), 6)
        col_institution_top11.update_one({"dept_id": inst_id, "year": year, "month": month},
                             {"$set": {"total_activities": total_activities,
                                       "total_participants": total_participants,
                                       "activate_indicators_count": activate_indicators_count,
                                       "quantity_indicators_count":quantity_indicators_count,
                                       "target": okr.get("okr", 0.000001),
                                       "ration": ration,
                                       "label": okr.get("dept_label"),
                                       "update": datetime.utcnow()
                                       }}, upsert=True)


def institution_task_top_ranking_v2(inst_id: str, year=None):
    """折算后新榜单（同1个单位同1年份内全部活动联系同一个科技者最多算2次）"""
    year = year if year else datetime.utcnow().year
    query = inst_query(inst_id)
    query["is_deleted"] = {"$ne": True}

    from_date = datetime(year, 1, 1)  # 默认当前年份的第一天的时刻epoch_year
    to_date = datetime(year + 1, 1, 1)
    query['end_time'] = {"$gte": from_date, "$lt": to_date}

    print(query)
    act_docs = col_activity.find(query).distinct("_id")

    total_activities = len(act_docs)

    pipeline = [
        {"$match": {"is_attended": True, "activity_id": {"$in": list(act_docs)}}},
        {"$lookup": {
            "from": "institution",
            "let": {"institution_ref_id": "$institution_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$institution_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"ocode": 1, "_id": 0}}
            ],
            "as": 'institution'
        }},
        # 过滤无效的引用
        {"$match": {"institution.0": {"$exists": True}}},
        {"$project": { "institution_id": 1, "activity_id": 1}},
    ]

    reg_docs = col_activity_institution.aggregate(pipeline)

    reg_docs = list(reg_docs) if reg_docs else []

    total_participants = len(reg_docs)

    # 激活指标
    activate_indicators_count = 0
    # 数量指标
    quantity_indicators_count = 0

    indicators = {}
    # 同一组织同一活动最多算两次
    for doc in reg_docs:
        inst = doc.get("institution_id")
        act_id = doc.get("activity_id")
        if inst not in indicators:
            indicators[inst] = set()
        if act_id not in indicators[inst]:
            quantity_indicators_count += 1
            indicators[inst].add(act_id)


    okr = col_okr.find_one({"year": year, "dept_id": inst_id})

    if okr:
        col_institution_top11e.update_one({"dept_id": inst_id, "year": year},
                                         {"$set": {"total_activities": total_activities,
                                                   "total_participants": total_participants,
                                                   "activate_indicators_count": activate_indicators_count,
                                                   "quantity_indicators_count": quantity_indicators_count,
                                                   "activate_indicators": 2,
                                                   "target": okr.get("institution_okr", 0.000001),
                                                   "label": okr.get("dept_label"),
                                                   "update": datetime.utcnow()
                                                   }}, upsert=True)


if __name__ == '__main__':
    # 62b945cd9aebef53937fecca
    # okr = col_okr.find()
    # for o in okr:
    #     dept = o.get("dept_id")
    #     for m in [(2023, 1), (2023, 2), (2023, 3), (2023, 4), (2023, 5), (2023, 6), (2023, 7), (2023, 8), (2023, 9),
    #               (2023, 10), (2023, 11), (2023, 12)]:
    #         year, month = m
    #         institution_task_top_by_month(inst_id=dept, year=year, month=month)

    okr = col_okr.find()
    for o in okr:
        dept = o.get("dept_id")
        institution_task_top_ranking_v2(dept)
